﻿namespace TwiMixer.Handlers
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Text.RegularExpressions;
    using System.Web;
    using TwiMixer.RESTAPI;
    using Twitterizer;

    /// <summary>
    /// apihandler 不同于通常的api 需要客户端支持自定义oauthurl 处理用户发来的rest请求
    /// </summary>
    public class RestApiHandler : IHttpHandler
    {
        /// <summary>
        /// 重用
        /// </summary>
        public bool IsReusable
        {
            get { return true; }
        }

        /// <summary>
        /// 处理用胡rest请求
        /// </summary>
        /// <param name="context">httpcontext</param>
        public void ProcessRequest(HttpContext context)
        {
            /*
             * oauth认证部分通过httpheader发送(twitterizer)
             * 参数以querystring方式发送
             * 
             */

            // 标记response获取是否正常 如401等则标记为true
            bool hasError = false;
            string responseBody, errorLog = string.Empty;
            string oauth_token, oauth_token_secret;

            // 获取path中的api类型以及oauth方法 例:/rest/sina/account/rate_limit.json
            string providerName = Regex.Match(context.Request.Path.Remove(0, 5), @"/[^/]+/([^/]+)/([^?]+)(\?\S+)?").Groups[1].Value;
            string restMethod = Regex.Match(context.Request.Path.Remove(0, 5), @"/[^/]+/([^/]+)/([^?]+)(\?\S+)?").Groups[2].Value;

            // 创建api访问对象
            APIProviderEnum api = (APIProviderEnum)Enum.Parse(typeof(APIProviderEnum), providerName);
            APIProvider provider = (APIProvider)APIProviderFactory.GetApiProvider(api);

            // 处理querystring 删除oauth_开头的(有的客户端oauth是通过querystring传递的)
            Dictionary<string, string> querys = new Dictionary<string, string>();
            string queryString = string.Empty;
            for (int i = 0; i < context.Request.QueryString.Count; i++)
            {
                if (!context.Request.QueryString.GetKey(i).Contains("oauth_"))
                {
                    querys.Add(context.Request.QueryString.GetKey(i), context.Request.QueryString[i]);
                }
            }

            // 获取token 从httlpheader或者querystring 并获取对应的secretkey
            if (context.Request.Headers["Authorization"] == null)
            {
                oauth_token = context.Request.QueryString["oauth_token"];
            }
            else
            {
                oauth_token = Regex.Match(context.Request.Headers["Authorization"], "oauth_token=\"(\\S+)\"").Groups[1].Value;
            }

            oauth_token_secret = Utility.GetTokenSecret(oauth_token, providerName);

            // 如果是POST 将form中的参数追加到querystring中
            if (context.Request.HttpMethod == "POST")
            {
                for (int i = 0; i < context.Request.Form.Count; i++)
                {
                    querys.Add(context.Request.Form.GetKey(i), context.Request.Form[i]);
                }
            }

            // 连接querystring
            foreach (var item in querys)
            {
                queryString += queryString.Length == 0 ? string.Empty : "&";
                queryString += item.Key + "=" + item.Value;
            }

            // Httpmethod以来源为准 此api不会将参数以form传递 应该可以只用GET
            WebRequestBuilder builder =
                new WebRequestBuilder(
                    new Uri(provider.RESTBaseUrl + restMethod + "?" + queryString), 
                    (HTTPVerb)Enum.Parse(typeof(HTTPVerb), context.Request.HttpMethod),
                    new OAuthTokens { ConsumerKey = provider.ConsumerKey, ConsumerSecret = provider.ConsumerSecret, AccessToken = oauth_token, AccessTokenSecret = oauth_token_secret });

            try
            {
                responseBody = new StreamReader(builder.ExecuteRequest().GetResponseStream()).ReadToEnd();
                context.Response.Write(responseBody);
            }
            catch (WebException ex)
            {
                errorLog = "\r\n\r\n====================" + ex.Message + "\r\n";
                hasError = true;
            }

            if (hasError)
            {
                errorLog += restMethod + "\r\n";
            }

            switch (restMethod)
            {
                case "account/rate_limit.json":
                    break;

                // 渣浪没对应api
                case "{username}/list.json":
                    break;

                case "statuses/metions.json":
                    break;

                case "direct_messages.json":
                    break;

                // 渣浪用的是uid不是username
                case "friends/ids/{username}.json":
                    break;

                // 渣浪没对应api
                case "users/lookup.json":
                    break;

                case "blocks/blocking.json":
                    break;

                case "statuses/home_timeline.json":
                    break;

                case "direct_messages/sent.json":
                    break;

                case "favorites.json":
                    break;

                // 渣浪没对应api
                case "{username}/lists/subcriptions.json":
                    break;

                case "trends/1.json":
                    break;

                // 把未处理的api请求保存到记录文件中 供以后实现
                default:
                    errorLog += "未实现 \r\n";
                    break;
            }

            Utility.SaveLog(errorLog, providerName);
            context.Response.End();
        }
    }
}